﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyNet.Componets.Core.Utils
{
    /// <summary>
    /// 算术辅助
    /// </summary>
    public static class MathUtil
    {
        #region 四舍五入
        /// <summary>
        /// 四舍五入
        /// </summary>
        /// <param name="value">数据源</param>
        /// <param name="targetPrecision">舍入后保留精度</param>
        /// <param name="sourcePrecision">舍入精度</param>
        /// <returns>舍入后的值</returns>
        public static decimal Round(decimal value, int targetPrecision, int sourcePrecision = 4)
        {
            return RoundByPrecision(value, targetPrecision, sourcePrecision);

        }

        private static decimal RoundByPrecision(decimal value, int targetPrecision, int sourcePrecision)
        {
            //将数据源转换成字符串
            var valueStr = value.ToString();
            //数据源小数点索引号
            var pointIndex = valueStr.IndexOf(".");
            //如果数据源没有小数，对数据源进行小数补位
            if (pointIndex <= 0)
            {
                return decimal.Parse(valueStr + "." + string.Empty.PadRight(targetPrecision, '0'));
            }
            //截取数据源的小数部分
            var decimalStr = valueStr.Substring(pointIndex + 1);
            //计算数据源小数精度位数
            sourcePrecision = decimalStr.Length > sourcePrecision ? sourcePrecision : decimalStr.Length;
            //数据源小数精度位数小于目标精度位数，进行对数据源进行精度位数补位
            if (targetPrecision > sourcePrecision)
            {
                return decimal.Parse(valueStr + string.Empty.PadRight(targetPrecision - sourcePrecision, '0'));
            }
            //数据源小数精度位数等于目标精度位数，无需进行舍入，直接返回数据源
            else if (targetPrecision == sourcePrecision)
            {
                return value;
            }
            //数据源小数精度位数大于目标精度位数，需要对数据源进行舍入
            else
            {
                for (int i = sourcePrecision; i > targetPrecision; i--)
                {
                    var factor = (decimal)(5 / Math.Pow(10, i));
                    value += factor;
                }
                return decimal.Parse(value.ToString().Substring(0, pointIndex + targetPrecision + 1));
            }
        }
        #endregion


    }
}
